<?php
// +----------------------------------------------------------------------
// | OneKeyAdmin [ Believe that you can do better ]
// +----------------------------------------------------------------------
// | Copyright (c) 2020-2023 http://onekeyadmin.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: MUKE <513038996@qq.com>
// +----------------------------------------------------------------------
namespace app\admin\controller;

use PDO;
use think\facade\View;
use think\exception\ValidateException;
use app\addons\File;
use app\admin\BaseController;
use app\admin\model\Catalog;
use app\admin\validate\Plugins as PluginsValidate;
/**
 * 插件管理
 */
class Plugins extends BaseController
{
    /**
     * 插件列表
     */
    public function list()
    {
        if ($this->request->isPost()) {
            $input = input();
            $list  = plugin_list(2);
            // 已安装
            if ($input['install'] == 1) {
                $input['ids'] = implode(',', array_column($list, 'id'));
            }
            // 远程插件
            $res   = api_post('plugins/getList', $input);
            $data  = [];
            $count = 0;
            if ($res['status'] === 'success') {
                $data  = $res['data'];
                $count = $res['count'];
                foreach ($data as $key => $val) {
                    $data[$key]['status'] = "";
                    $data[$key]['now_version_number'] = "未安装";
                    $data[$key]['cover'] = config('app.api').$val['cover'];
                    foreach ($list as $k => $v) {
                        if ($val['name'] === $v['name']) {
                            $data[$key]['status'] = $v['status'];
                            $data[$key]['now_version_number'] = implode('.', str_split(str_replace('.', '', $v['version'])));
                        }
                    }
                }
                // 未发布/正在开发的插件
                if ($input['install'] == 1) {
                    foreach ($list as $key => $value) {
                        if (! isset($value['id'])) {
                            $item = $value;
                            $item['id'] = "";
                            $item['now_version_number'] = '1.0.0';
                            $item['user_nickname'] = '本站';
                            $item['download'] = 0;
                            array_push($data, $item);
                        }
                    }
                }
            }
            return json(['status' => 'success', 'message' => '获取成功', 'data' => $data, 'count' => $count, 'publicMenu'=> $this->request->publicMenu]);
        } else {
            // 分类
            $catalog = cache('pluginsCatalogList');
            if (empty($catalog)) {
                $res = api_post('plugins/getCatalogList');
                $catalog = $res['status'] === 'success' ? $res['data'] : [];
                cache('pluginsCatalogList', $catalog);
            }
            View::assign('catalog', $catalog);
            return View::fetch();
        }
    }

    /**
     * 删除指定资源
     */
    public function delete()
    {
        try {
            $input = input();
            validate(PluginsValidate::class)->scene('delete')->check($input);
            $path = plugin_path() . $input['name'];
            File::delDirAndFile($path);
            return json(['status' => 'success', 'message' => '插件卸载成功']);
        } catch ( ValidateException $e ) {
            return json($e->getError());
        }
    }

    /**
     * 保存更新的资源
     */
    public function update()
    {
        try {
            $input = input();
            validate(PluginsValidate::class)->scene('update')->check($input);
            $file = plugin_path() . $input['name'] . '/info.php';
            if (is_file($file)) {
                if (is_writable($file)) {
                    $info = include($file);
                    $info['status'] = (int) $input['value'];
                    $text = "<?php\nreturn ".var_export($info,true).";";
                    $fopen = fopen($file, 'w');
                    if($fopen){
                        fwrite($fopen, $text);
                        fclose($fopen);
                        $message = $input['value'] === 1 ? '插件开启成功' : '插件关闭成功';
                        return json(['status' => 'success', 'message' => $message]);
                    } else {
                        return json(['status' => 'error', 'message' => '文件写入失败']);
                    }
                } else {
                    return json(['status' => 'error', 'message' => '插件文件权限不足']);
                }
            } else {
                return json(['status' => 'error', 'message' => '插件不存在']);
            }
        } catch ( ValidateException $e ) {
            return json($e->getError());
        }
    }

    /**
     * 详情
     */
    public function details()
    {
        if ($this->request->isPost()) {
            $input = input();
            $res   = api_post('plugins/getDetails', $input);
            return json($res);
        }
    }

    /**
     * 评论(分页)
     */
    public function comment()
    {
        if ($this->request->isPost()) {
            $input = input();
            $res   = api_post('plugins/getComment', $input);
            return json($res);
        }
    }

    /**
     * 创建订单
     */
    public function createOrder()
    {
        if ($this->request->isPost()) {
            $input = input();
            $res   = api_post('plugins/createOrder', $input);
            return json($res);
        }
    }

    /**
     * 安装包初始化
     */
    public function init($input, $res)
    {
        $path = plugin_path() . $input['name'] . '/';
        // 创建文件
        File::create($path . 'file.zip', base64_decode($res['data']['zip']));
        // 执行解压
        File::extract($path . 'file.zip', $path);
        // 执行数据
        if (is_file($path . 'file.sql')) {
            $sql  = file_get_contents(($path . 'file.sql'));
            $info = "mysql:dbname=".env('database.database').";host=".env('database.hostname')."";
            $db   = new PDO($info, env('database.username'), env('database.password'));
            $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 0);
            $db->exec($sql);
        }
        // 添加分类信息
        $route = $path.'route.php';
        if (is_file($route)) {
            $route = include($route);
            foreach ($route as $key => $val) {
                if ($val['type'] === 'catalog') {
                    foreach ($this->request->langAllow as $k => $v) {
                        $exist = Catalog::where('seo_url',$val['search']['type'])->where('language',$v['name'])->count();
                        if (empty($exist)) {
                            Catalog::create([
                                'pid'                 => 0,
                                'num'                 => 0,
                                'group_id'            => [],
                                'title'               => $val['title'],
                                'cover'               => '',
                                'content'             => "",
                                'field'               => [],
                                'seo_url'             => $val['search']['type'],
                                'seo_title'           => "",
                                'seo_keywords'        => "",
                                'seo_description'     => "",
                                'links_type'          => 0,
                                'links_value'         => '',
                                'sort'                => 0,
                                'type'                => $val['search']['type'],
                                'show'                => 1,
                                'status'              => 1,
                                'create_time'         => date('Y-m-d H:i:s'),
                                'language'            => $v['name'],
                                'mobile'              => 1,
                            ]);
                        }
                    }
                }
            }
        }
        // 插件视图移动
        if (is_writable(theme_path())) {
            $oldView = $path.'index/view/';
            $oldFile = File::getDir($oldView);
            $newView = theme_path_now();
            foreach ($oldFile as $key => $value) {
                if (is_file($value)) {
                    $newFile = $newView . str_replace($oldView, '', $value);
                    if (! is_file($newFile)) {
                        $content = file_get_contents($value);
                        File::create($newFile, $content);
                    }
                }
            }
        }
        // 初始化文件
        $initFile = $path . 'init.php';
        if (is_file($initFile)) {
            $bool = include($initFile);
            if ($bool) {
                unlink($initFile);
            }
        }
        // 初始化信息
        $info  = $res['data']['info'];
        $text  = "<?php\nreturn ".var_export($info,true).";";
        $fopen = fopen($path.'info.php', 'w');
        if($fopen){
            fwrite($fopen, $text);
            fclose($fopen);
        }
    }

    /**
     * 上传插件包安装
     */
    public function upload() 
    {
        if (! is_dir(plugin_path())) {
            mkdir(plugin_path(), 0777, true);
        }
        if (is_writable(plugin_path())) {
            $input = input();
            $arr   = explode('.', $_FILES['file']['name']);
            $input['name'] = $arr[0];
            $res = api_post('plugins/orderFile', $input);
            if ($res['status'] === 'success') {
                $this->init($input, $res);
                return json(['status' => 'success', 'message' => '插件安装成功']);
            } else {
                return json($res);
            }
        } else {
            return json(['status' => 'error', 'message' => '插件目录没有写入权限']);
        }
    }

    /**
     * 安装/更新插件
     */
    public function install()
    {
        if (! is_dir(plugin_path())) {
            mkdir(plugin_path(), 0777, true);
        }
        if (is_writable(plugin_path())) {
            try {
                $input = input();
                validate(PluginsValidate::class)->scene('install')->check($input);
                $data['type'] = $input['install_type'];
                $data['plugins_id'] = $input['id'];
                $res = api_post('plugins/getFile', $data);
                if ($res['status'] === 'success') {
                    $this->init($input, $res);
                    return json(['status' => 'success', 'message' => '插件安装成功']);
                } else {
                    return json($res);
                }
            } catch ( ValidateException $e ) {
                return json($e->getError());
            }
        } else {
            return json(['status' => 'error', 'message' => '插件目录没有写入权限']);
        }
    }

    /**
     * 插件跳转
     */
    public function index()
    {
        $class     = ucfirst($this->request->pluginClass);
        $action    = $this->request->pluginAction;
        $route     = $this->request->pluginRoute;
        $namespace = $this->request->pluginNamespace;
        $plugins   = app("$namespace\\$class");
        // 插件模板配置
        $viewPath  = str_replace('\\', '/', public_path() . "$route\\view\\");
        View::config([
            "view_path" => $viewPath,
        ]);
        // 加载插件common头尾文件
        $common = [];
        foreach (['Header','Footer'] as $key => $val) {
            $commonFile = strtolower($val) . '.html'; 
            $commonPath = str_replace('\\', '/', public_path() . "$route\\view\\common\\$commonFile");
            $commonName = 'plugin' . $val;
            if (is_file($commonPath)) {
                $common[$commonName] = $commonPath;
            }
        }
        
        View::assign($common);
        // 执行插件
        return $plugins->$action();
    }
}
